﻿using System.Collections;
using System.Collections.Generic;
using LuaInterface;
using LuaFramework;
using System;
using UnityEngine;
using Assets.Script.Config;

public enum SkillPartState
{
    Damage,
    Treatment,
    Other,
}

public enum NormalAttackState
{
    Normal,
    FightBack,
    Sputtering,
}

public enum BeforeDoActionState
{
    BuffOff,
    Damage,
    Treatment,
}

public enum FragmentStateType
{
    Wait,
    BeforeAction,
    BeforeSkill,
    Attack,
    AfterSkill,
}

public class BattleFragment
{
    #region 数据转换
    // 本片段行动者
    private int _doActionTroopID;
    // 判断技能是不是在普攻后
    private bool _skillAfterNormalAttack = false;
    // 判断当前伤害是技能还是普攻
    private bool _isSkillEffect = false;
    // 普攻前释放的技能
    private List<BattleSkillResult> _beforeNormalAttackSkillList = new List<BattleSkillResult>();
    // 普攻后释放的技能
    private List<BattleSkillResult> _afterNormalAttackSkillList = new List<BattleSkillResult>();
    // 普攻列表
    private List<BattleNormalAttackTask> _normalAttackTaskList = new List<BattleNormalAttackTask>();
    // 下一个普通攻击的类型
    private NormalAttackState _nextNormalAttackState = NormalAttackState.Normal;
    // 吸血造成的回复值
    private int _makeVampireNum = -1;
    // 行动前结算事件列表
    private List<BeforeDoAction> _beforeDoActionList = new List<BeforeDoAction>();
    // 本次行动是否为空
    private bool _nilFragment = true;

    /// <summary>
    /// 设置这个片段的行动者
    /// </summary>
    /// <param name="heroID"></param>
    public void SetDoActionHeroID(long heroID)
    {
        _doActionTroopID = BattleMgr.Instance.GetTroopIndexByHeroId(heroID);
    }

    /// <summary>
    /// 添加释放的技能
    /// </summary>
    public void AddSkillResult(int skillID,bool isSing =false)
    {
        _nilFragment = false;
        BattleSkillResult bsr = new BattleSkillResult();
        bsr._skillID = skillID;
        bsr._sing = isSing;
        _isSkillEffect = true;
        AddPreLoadSkillID(bsr._skillID);
        if (_skillAfterNormalAttack)
        {
            _afterNormalAttackSkillList.Add(bsr);
        }
        else
        {
            _beforeNormalAttackSkillList.Add(bsr);
        }
    }

    /// <summary>
    /// 添加技能组件
    /// </summary>
    /// <param name="skillEffID"></param>
    /// <param name="value1"></param>
    /// <param name="value2"></param>
    public void AddSkillPart(long targetID, int skillEffID, int value1, int value2, bool isCri, SkillPartState skillPartState = SkillPartState.Other)
    {
        _nilFragment = false;
        BattleSkillPart bsp = new BattleSkillPart();
        bsp._targetID = BattleMgr.Instance.GetTroopIndexByHeroId(targetID);
        bsp._skillEffID = skillEffID;
        bsp._value1 = value1;
        bsp._value2 = value2;
        bsp._partState = skillPartState;
        bsp._isCri = isCri;
        AddPreloadSkillEffID(skillEffID);
        if (_makeVampireNum >= 0)
        {
            bsp._vampireNum = _makeVampireNum;
            _makeVampireNum = -1;
        }
        if (_skillAfterNormalAttack)
        {
            _afterNormalAttackSkillList[_afterNormalAttackSkillList.Count - 1]._battleSkillPartList.Add(bsp);
        }
        else
        {
            _beforeNormalAttackSkillList[_beforeNormalAttackSkillList.Count - 1]._battleSkillPartList.Add(bsp);
        }
    }

    /// <summary>
    /// 战斗中造成伤害专用，对应22号
    /// </summary>
    /// <param name="targetID"></param>
    /// <param name="damageNum"></param>
    /// <param name="leftNum"></param>
    /// <param name="skillEffID"></param>
    public void MakeDamage(long targetID, int damageNum, int leftNum, int skillEffID,bool isCri)
    {
        _nilFragment = false;
        if (_isSkillEffect)
        {
            AddSkillPart(targetID, skillEffID, damageNum, leftNum,isCri ,SkillPartState.Damage);
            AddPreloadSkillEffID(skillEffID);
        }
        else
        {
            if (_normalAttackTaskList.Count == 0) 
            {
                //Debug.LogFormat("庇护状态处理BUF 有点问题先屏蔽掉");
                return;
            }

            int normalAttackIndex = _normalAttackTaskList.Count - 1;
            int nromalAttackPartIndex = _normalAttackTaskList[normalAttackIndex]._normalAttackPartList.Count - 1;
            //BattleNormalAttackPart currentBnap = _normalAttackTaskList[_normalAttackTaskList.Count - 1]._normalAttackPartList[_normalAttackTaskList[_normalAttackTaskList.Count - 1]._normalAttackPartList.Count - 1];
            BattleNormalAttackPart currentBnap = _normalAttackTaskList[normalAttackIndex]._normalAttackPartList[nromalAttackPartIndex];
            currentBnap._damageNum = damageNum;
            currentBnap._isCri = isCri;
            if (_makeVampireNum >= 0)
            {
                currentBnap._vampireNum = _makeVampireNum;
                _makeVampireNum = -1;
            }
        }
    }

    /// <summary>
    /// 技能回血
    /// </summary>
    /// <param name="targetID"></param>
    /// <param name="treatNum"></param>
    /// <param name="leftNum"></param>
    /// <param name="skillEffID"></param>
    public void MakeTreatment(long targetID, int treatNum, int leftNum, int skillEffID)
    {
        _nilFragment = false;
        if (_isSkillEffect)
        {
            //AddSkillPart(BattleMgr.Instance.GetTroopIndexByHeroId(targetID), skillEffID, treatNum, leftNum, SkillPartState.Treatment);
            AddSkillPart(targetID, skillEffID, treatNum, leftNum,false, SkillPartState.Treatment);
        }
        AddPreloadSkillEffID(skillEffID);
    }

    /// <summary>
    /// 战斗中造成吸血专用，对应31号
    /// </summary>
    /// <param name="damage"></param>
    public void MakeVampire(int vampireNum)
    {
        _nilFragment = false;
        _makeVampireNum = vampireNum;
    }

    /// <summary>
    /// 添加普攻结构
    /// </summary>
    /// <param name="attackHeroID"></param>
    /// <param name="beAttackHeroID"></param>
    public void AddNormalAttack(long attackHeroID, long beAttackHeroID)
    {
        _nilFragment = false;
        _isSkillEffect = false;
        _skillAfterNormalAttack = true;
        if (_nextNormalAttackState == NormalAttackState.Normal)
        {
            BattleNormalAttackTask bnat = new BattleNormalAttackTask();
            _normalAttackTaskList.Add(bnat);
        }
        BattleNormalAttackPart bnap = new BattleNormalAttackPart();
        bnap._attackTroopID = BattleMgr.Instance.GetTroopIndexByHeroId(attackHeroID);
        bnap._beAttackTroopID = BattleMgr.Instance.GetTroopIndexByHeroId(beAttackHeroID);
        bnap._normalAttackState = _nextNormalAttackState;
        _normalAttackTaskList[_normalAttackTaskList.Count - 1]._normalAttackPartList.Add(bnap);
        switch (_nextNormalAttackState)
        {
            case NormalAttackState.Normal:
                _normalAttackTaskList[_normalAttackTaskList.Count - 1]._normalAttackIndex = _normalAttackTaskList[_normalAttackTaskList.Count - 1]._normalAttackPartList.Count - 1;
                break;
            case NormalAttackState.FightBack:
                _normalAttackTaskList[_normalAttackTaskList.Count - 1]._fightBackIndex = _normalAttackTaskList[_normalAttackTaskList.Count - 1]._normalAttackPartList.Count - 1;
                break;
            case NormalAttackState.Sputtering:
                _normalAttackTaskList[_normalAttackTaskList.Count - 1]._sputteringList.Add(_normalAttackTaskList[_normalAttackTaskList.Count - 1]._normalAttackPartList.Count - 1);
                break;
        }
        _nextNormalAttackState = NormalAttackState.Normal;
       
    }

    public void ChangeNextNormalAttackState(NormalAttackState nextNormalAttackState)
    {
        _nilFragment = false;
        _nextNormalAttackState = nextNormalAttackState;
    }
    /// <summary>
    /// 行动前结算
    /// </summary>
    /// <param name="selfHeroID"></param>
    /// <param name="fromHeroID"></param>
    /// <param name="skillID"></param>
    /// <param name="skillEffID"></param>
    /// <param name="changeValue"></param>
    /// <param name="beforeDoActionState"></param>
    public void AddBeforeDoAction(long selfHeroID, long fromHeroID, int skillID, int skillEffID, int changeValue, BeforeDoActionState beforeDoActionState)
    {
        _nilFragment = false;
        BeforeDoAction bda = new BeforeDoAction();
        bda._beforeDoActionState = beforeDoActionState;
        bda._selfTroopID = BattleMgr.Instance.GetTroopIndexByHeroId(selfHeroID);
        bda._fromTroopID = BattleMgr.Instance.GetTroopIndexByHeroId(fromHeroID);
        bda._skillID = skillID;
        bda._skillEffID = skillEffID;
        bda._changeValue = changeValue;
        _beforeDoActionList.Add(bda);
        AddPreloadSkillEffID(skillEffID);
    }
    /// <summary>
    /// 添加预加载需要的skilleffID
    /// </summary>
    /// <param name="skillEffID"></param>
    public void AddPreloadSkillEffID(int skillEffId)
    {
        int beId= GetBeIdBySkEff(skillEffId);

        if (!BattleMgr.Instance.NeedPreloadBeList.Contains(beId))
        {
            BattleMgr.Instance.NeedPreloadBeList.Add(beId);
        }
    }
    public void AddPreLoadSkillID(int skillId) 
    {
        int beId = GetBeIdBySk(skillId);

        if (!BattleMgr.Instance.NeedPreloadBeList.Contains(beId))
        {
            BattleMgr.Instance.NeedPreloadBeList.Add(beId);
        }
    }

    #endregion

    #region 片段逻辑
    private FragmentStateType _fragmentState = FragmentStateType.Wait;

    #region 计时器
    // 
    public delegate void TimeInterval();
    // 
    private Dictionary<TimeInterval, float> _timeIntervalDic = new Dictionary<TimeInterval, float>();
    /// <summary>
    /// 添加计时器事件
    /// </summary>
    /// <param name="interval"></param>
    /// <param name="time"></param>
    public void AddInterval(TimeInterval interval, float time)
    {
        if (time == 0f)
        {
            interval();
            return;
        }
        if (interval != null)
        {
            _timeIntervalDic[interval] = BattleMgr.Instance.Timer + time;
        }
    }

    /// <summary>
    /// 移除计时器事件
    /// </summary>
    /// <param name="interval"></param>
    public void RemoveInterval(TimeInterval interval)
    {
        if (interval != null)
        {
            if (_timeIntervalDic.ContainsKey(interval))
            {
                _timeIntervalDic.Remove(interval);
            }
        }
    }

    /// <summary>
    /// 计时器运行
    /// </summary>
    private void TimeIntervalUpadte()
    {
        if (_timeIntervalDic.Count > 0)
        {
            List<TimeInterval> timeIntervalKeyList = new List<TimeInterval>(_timeIntervalDic.Keys);
            for (int i = 0; i < timeIntervalKeyList.Count; i++)
            {
                if (_timeIntervalDic[timeIntervalKeyList[i]] <= BattleMgr.Instance.Timer)
                {
                    TimeInterval ti = timeIntervalKeyList[i];
                    _timeIntervalDic.Remove(timeIntervalKeyList[i]);
                    ti();
                }
            }
        }
    }

    #endregion

    #region 播放技能特效

    private List<BattleMoveEffect> _battleMoveEffectList = new List<BattleMoveEffect>();

    private void BattleMoveEffectUpdate()
    {
        if (_battleMoveEffectList.Count > 0)
        {
            List<int> needRemoveList = new List<int>();
            for (int i = _battleMoveEffectList.Count - 1; i >= 0; i--)
            {
                if (_battleMoveEffectList[i]._moveFinishTime <= BattleMgr.Instance.Timer)
                {
                    needRemoveList.Add(i);
                    if (_battleMoveEffectList[i]._makeCheck)
                    {
                        BattleEffect be = ConfigManager.Instance.BattleEffectLoader.GetInfoById(_battleMoveEffectList[i]._battleEffID);
                        for (int j = 0; j < be._battleEffectPartList.Count; j++)
                        {
                            BattleEffectPart bep = ConfigManager.Instance.BattleEffectPartLoader.GetInfoById(be._battleEffectPartList[j]);
                            if (bep._isTrigger)
                            {
                                GameObject effect = GameObject.Instantiate(BattleMgr.Instance.EffectPartGoDic[bep._effectPartId], _battleMoveEffectList[i]._flyObj.transform.position, Quaternion.identity) as GameObject;
                            }
                        }
                    }
                }
                else
                {
                    _battleMoveEffectList[i]._flyObj.transform.Translate(_battleMoveEffectList[i]._moveDir * Time.fixedDeltaTime, Space.World);
                }
            }
            for (int i = 0; i < needRemoveList.Count; i++)
            {
                GameObject.Destroy(_battleMoveEffectList[needRemoveList[i]]._flyObj);
                _battleMoveEffectList.RemoveAt(needRemoveList[i]);
            }
        }
    }

    private float PlayEffect(BeforeDoAction beforeDoAction)
    {
        int battleEffID = GetBeIdBySkEff(beforeDoAction._skillEffID);
      
        if (battleEffID == -1)
        {
            return 1f;
        }
        BattleEffect be = ConfigManager.Instance.BattleEffectLoader.GetInfoById(battleEffID);
        SkillPartState skillState = SkillPartState.Other;
        if (beforeDoAction._beforeDoActionState == BeforeDoActionState.Damage)
        {
            skillState = SkillPartState.Damage;
        }
        else if (beforeDoAction._beforeDoActionState == BeforeDoActionState.Treatment)
        {
            skillState = SkillPartState.Treatment;
        }
        if (be._battleSkillEffectShowType == 1)
        {
            return PlayFromTroopEffect(beforeDoAction._selfTroopID, beforeDoAction._fromTroopID, be, beforeDoAction._changeValue, skillState, -1,false);
        }
        else
        {
            return PlayNormalEffect(beforeDoAction._selfTroopID, beforeDoAction._fromTroopID, be, beforeDoAction._changeValue, skillState, -1,false);
        }
    }

    private float PlayEffect(BattleSkillPart battleSkillPart)
    {
        int battleEffID = GetBeIdBySkEff(battleSkillPart._skillEffID);
     
        if (battleEffID == -1)
        {
            return 0.2f;
        }
        BattleEffect be = ConfigManager.Instance.BattleEffectLoader.GetInfoById(battleEffID);
        if (be._battleSkillEffectShowType == 1)
        {
            return PlayFromTroopEffect(battleSkillPart._targetID, _doActionTroopID, be, battleSkillPart._value1, battleSkillPart._partState, battleSkillPart._vampireNum,battleSkillPart._isCri);
        }
        else
        {
            return PlayNormalEffect(battleSkillPart._targetID, _doActionTroopID, be, battleSkillPart._value1, battleSkillPart._partState, battleSkillPart._vampireNum,battleSkillPart._isCri);
        }
    }

    private float PlayEffect(BattleSkillResult skillResult) 
    {
        _skillTag.Clear();
        Skill skillProto = ConfigManager.Instance.SkillLoader.GetInfoById(skillResult._skillID);
        if (skillProto.effectId == 0)
        {
            //没有特效时候是0
            //Debug.LogFormat("这个技能{0} 没有配特效ID！！！！！！！！！！！！！！！", skillResult._skillID);
            return 0.2f;
        }
        BattleEffect be = ConfigManager.Instance.BattleEffectLoader.GetInfoById(skillProto.effectId);
        float maxEff = 0;
        for (int i = 0; i < skillResult._battleSkillPartList.Count; i++)
        {

            if (!_skillTag.Contains(skillResult._battleSkillPartList[i]._targetID))
            {
                int tagId = skillResult._battleSkillPartList[i]._targetID;
                _skillTag.Add(tagId);
                float effTime = 0;

                if (be._battleSkillEffectShowType == 1)
                {
                    effTime = PlayFromTroopEffect(tagId, _doActionTroopID, be, delegate() 
                    {
                        //扣血操作
                        for (int j = 0; j < skillResult._battleSkillPartList.Count; j++)
                        {
                            if (tagId == skillResult._battleSkillPartList[j]._targetID)
                            {
                                switch (skillResult._battleSkillPartList[j]._partState)
                                {
                                    case SkillPartState.Treatment:
                                        TroopHpChange(tagId, _doActionTroopID, skillResult._battleSkillPartList[j]._value1, skillResult._battleSkillPartList[j]._isCri, true);
                                        break;
                                    case SkillPartState.Damage:
                                        EffectMakeDamage(tagId, _doActionTroopID, skillResult._battleSkillPartList[j]._value1, skillResult._battleSkillPartList[j]._isCri);
                                        break;
                                    case SkillPartState.Other:

                                        break;
                                }
                                if (skillResult._battleSkillPartList[j]._vampireNum != -1)
                                {
                                    TroopHpChange(tagId, _doActionTroopID, skillResult._battleSkillPartList[j]._vampireNum, skillResult._battleSkillPartList[j]._isCri, true);
                                }
                            }
                            BattleMgr.Instance.TroopBuffGet(_doActionTroopID, tagId, skillResult._skillID, skillResult._battleSkillPartList[j]._skillEffID, skillResult._battleSkillPartList[j]._value1);

                        }

                    });

                }
                else
                {
                    effTime = PlayNormalEffect(tagId, _doActionTroopID, be, delegate() 
                    {
                        //扣血操作
                        for (int j = 0; j < skillResult._battleSkillPartList.Count; j++) 
                        {
                            if (tagId == skillResult._battleSkillPartList[j]._targetID) 
                            {
                                switch (skillResult._battleSkillPartList[j]._partState)
                                {
                                    case SkillPartState.Treatment:
                                        TroopHpChange(tagId, _doActionTroopID, skillResult._battleSkillPartList[j]._value1,skillResult._battleSkillPartList[j]._isCri,true);
                                        break;
                                    case SkillPartState.Damage:
                                        EffectMakeDamage(tagId, _doActionTroopID, skillResult._battleSkillPartList[j]._value1, skillResult._battleSkillPartList[j]._isCri);
                                        break;
                                    case SkillPartState.Other:

                                        break;
                                }
                                if (skillResult._battleSkillPartList[j]._vampireNum != -1)
                                {
                                    TroopHpChange(tagId, _doActionTroopID, skillResult._battleSkillPartList[j]._vampireNum, skillResult._battleSkillPartList[j]._isCri,true);
                                }
                            }
                            BattleMgr.Instance.TroopBuffGet(_doActionTroopID, tagId, skillResult._skillID,skillResult._battleSkillPartList[j]._skillEffID, skillResult._battleSkillPartList[j]._value1);

                        }
                    });
                }
                if (effTime > maxEff)
                {
                    maxEff = effTime;
                }
            }
        }
        return maxEff;
    }

    private bool _stillLookAtTarget;

    public float PlayNormalEffect(int targetTroopID, int fromTroopID, BattleEffect battleEffect, int changeValue, SkillPartState skillPartState, int vampireNum,bool isCri)
    {
        List<int> effectPartIdList = battleEffect._battleEffectPartList;
        float checkTime = 0f;
        Vector3 targetPos = BattleMgr.Instance.TroopDic[targetTroopID].GetTroopCenter();
        float moveToTargetTroopTime = 0f;
        if (!_stillLookAtTarget)
        {
            moveToTargetTroopTime = BattleCameraCtrl.Instance.MoveToNormalEffectPos(fromTroopID, targetTroopID);
        }
        float backToNormalTime = BattleCameraCtrl.Instance.GetBackFromTargetTroopTime(targetTroopID);
        if (_notNeedBack)
        {
            backToNormalTime = 0f;
        }
        for (int i = 0; i < effectPartIdList.Count; i++)
        {
            BattleEffectPart bep = ConfigManager.Instance.BattleEffectPartLoader.GetInfoById(effectPartIdList[i]);
            if (bep._checkTime != -1)
            {
                checkTime = bep._checkTime;
            }
        }
        AddInterval(delegate()
        {
            for (int i = 0; i < effectPartIdList.Count; i++)
            {
                BattleEffectPart bep = ConfigManager.Instance.BattleEffectPartLoader.GetInfoById(effectPartIdList[i]);
                if (bep._isTrigger)
                {
                    continue;
                }
                GameObject go = GameObject.Instantiate(BattleMgr.Instance.EffectPartGoDic[bep._effectPartId], targetPos, Quaternion.identity) as GameObject;
                GameObject.Destroy(go, bep._destroyTime);
            }
            AddInterval(delegate()
            {
                switch (skillPartState)
                {
                    case SkillPartState.Treatment:
                        TroopHpChange(targetTroopID, fromTroopID, changeValue,isCri,true);
                        break;
                    case SkillPartState.Damage:
                        EffectMakeDamage(targetTroopID, fromTroopID, changeValue,isCri);
                        break;
                    case SkillPartState.Other:

                        break;
                }
            }, checkTime);
            if (vampireNum != -1)
            {
                AddInterval(delegate()
                {
                    TroopHpChange(fromTroopID, fromTroopID, vampireNum,isCri,true);
                }, checkTime);
            }
            //Debug.Log(battleEffect._lastTime);
            if (_notNeedBack)
            {
                _stillLookAtTarget = true;
            }
            else
            {
                AddInterval(delegate()
                {
                    BattleCameraCtrl.Instance.BackFromTargetTroop();
                    _stillLookAtTarget = false;
                }, battleEffect._lastTime);
            }
        }, moveToTargetTroopTime);
        return battleEffect._lastTime + backToNormalTime + moveToTargetTroopTime + 0.5f;
    }

    public float PlayNormalEffect(int targetTroopID, int fromTroopID, BattleEffect battleEffect, Action doDamageFunc) 
    {
        List<int> effectPartIdList = battleEffect._battleEffectPartList;
        float checkTime = 0f;
        Vector3 targetPos = BattleMgr.Instance.TroopDic[targetTroopID].GetTroopCenter();
        float moveToTargetTroopTime = 0f;
        if (!_stillLookAtTarget)
        {
            moveToTargetTroopTime = BattleCameraCtrl.Instance.MoveToNormalEffectPos(fromTroopID, targetTroopID);
        }
        float backToNormalTime = BattleCameraCtrl.Instance.GetBackFromTargetTroopTime(targetTroopID);
        if (_notNeedBack)
        {
            backToNormalTime = 0f;
        }
        for (int i = 0; i < effectPartIdList.Count; i++)
        {
            BattleEffectPart bep = ConfigManager.Instance.BattleEffectPartLoader.GetInfoById(effectPartIdList[i]);
            if (bep._checkTime != -1)
            {
                checkTime = bep._checkTime;
            }
        }

        AddInterval(delegate()
        {
            for (int i = 0; i < effectPartIdList.Count; i++)
            {
                BattleEffectPart bep = ConfigManager.Instance.BattleEffectPartLoader.GetInfoById(effectPartIdList[i]);
                if (bep._isTrigger)
                {
                    continue;
                }
                GameObject go = GameObject.Instantiate(BattleMgr.Instance.EffectPartGoDic[bep._effectPartId], targetPos, Quaternion.identity) as GameObject;
                GameObject.Destroy(go, bep._destroyTime);
            }
            AddInterval(delegate()
            {
                doDamageFunc();
            }, checkTime);

        }, moveToTargetTroopTime);
        return battleEffect._lastTime + backToNormalTime + moveToTargetTroopTime + 0.5f;
    }

    public float PlayFromTroopEffect(int targetTroopID, int fromTroopID, BattleEffect battleEffect, Action doDamageFunc) 
    {
        float checkTime = 0f;
        Vector3 fromPos = BattleMgr.Instance.TroopDic[fromTroopID].GetTroopCenter();
        Vector3 targetPos = BattleMgr.Instance.TroopDic[targetTroopID].GetTroopCenter();
        List<int> effectPartIdList = battleEffect._battleEffectPartList;
        for (int i = 0; i < effectPartIdList.Count; i++)
        {
            BattleEffectPart bep = ConfigManager.Instance.BattleEffectPartLoader.GetInfoById(effectPartIdList[i]);
            if (bep._isTrigger)
            {
                continue;
            }
            if (bep._isRemoteObj)
            {
                GameObject go = GameObject.Instantiate(BattleMgr.Instance.EffectPartGoDic[bep._effectPartId], fromPos, Quaternion.identity) as GameObject;
                go.transform.LookAt(targetPos);
                BattleMoveEffect bme = new BattleMoveEffect();
                bme._fromTroopID = fromTroopID;
                bme._targetTroopID = targetTroopID;
                bme._makeCheck = !bep._notTakeTrigger;
                bme._flyObj = go;
                bme._moveDir = (targetPos - fromPos).normalized * bep._moveSpeed;
                bme._battleEffID = battleEffect._effectId;
                float moveNeedTime = Vector3.Distance(targetPos, fromPos) / bep._moveSpeed;
                bme._moveFinishTime = BattleMgr.Instance.Timer + moveNeedTime;
                if (bme._makeCheck)
                {
                    checkTime = moveNeedTime;
                }
                _battleMoveEffectList.Add(bme);
            }
            else
            {
                GameObject go = GameObject.Instantiate(BattleMgr.Instance.EffectPartGoDic[bep._effectPartId], fromPos, Quaternion.identity) as GameObject;
                GameObject.Destroy(go, bep._destroyTime);
            }
        }

        AddInterval(delegate()
        {
            doDamageFunc();

        }, checkTime);
        return checkTime + 0.1f;
    }

    public float PlayFromTroopEffect(int targetTroopID, int fromTroopID, BattleEffect battleEffect, int changeValue, SkillPartState skillPartState, int vampireNum,bool isCri)
    {
        float checkTime = 0f;
        Vector3 fromPos = BattleMgr.Instance.TroopDic[fromTroopID].GetTroopCenter();
        Vector3 targetPos = BattleMgr.Instance.TroopDic[targetTroopID].GetTroopCenter();
        List<int> effectPartIdList = battleEffect._battleEffectPartList;
        for (int i = 0; i < effectPartIdList.Count; i++)
        {
            BattleEffectPart bep = ConfigManager.Instance.BattleEffectPartLoader.GetInfoById(effectPartIdList[i]);
            if (bep._isTrigger)
            {
                continue;
            }
            if (bep._isRemoteObj)
            {
                GameObject go = GameObject.Instantiate(BattleMgr.Instance.EffectPartGoDic[bep._effectPartId], fromPos, Quaternion.identity) as GameObject;
                go.transform.LookAt(targetPos);
                BattleMoveEffect bme = new BattleMoveEffect();
                bme._fromTroopID = fromTroopID;
                bme._targetTroopID = targetTroopID;
                bme._makeCheck = !bep._notTakeTrigger;
                bme._flyObj = go;
                bme._moveDir = (targetPos - fromPos).normalized * bep._moveSpeed;
                bme._battleEffID = battleEffect._effectId;
                float moveNeedTime = Vector3.Distance(targetPos, fromPos) / bep._moveSpeed;
                bme._moveFinishTime = BattleMgr.Instance.Timer + moveNeedTime;
                if (bme._makeCheck)
                {
                    checkTime = moveNeedTime;
                }
                _battleMoveEffectList.Add(bme);
            }
            else
            {
                GameObject go = GameObject.Instantiate(BattleMgr.Instance.EffectPartGoDic[bep._effectPartId], fromPos, Quaternion.identity) as GameObject;
                GameObject.Destroy(go, bep._destroyTime);
            }
        }

        AddInterval(delegate()
        {
            switch (skillPartState)
            {
                case SkillPartState.Treatment:
                    TroopHpChange(targetTroopID, fromTroopID, changeValue,isCri,true);
                    break;
                case SkillPartState.Damage:
                    EffectMakeDamage(targetTroopID, fromTroopID, changeValue,isCri);
                    break;
                case SkillPartState.Other:

                    break;
            }
        }, checkTime);
        if (vampireNum != -1)
        {
            AddInterval(delegate()
            {
                TroopHpChange(fromTroopID, fromTroopID, vampireNum,isCri,true);
            }, checkTime);
        }
        return checkTime + 0.1f;
    }

    public void EffectMakeDamage(int targetTroopID, int fromTroopID, int damageNum,bool isCri)
    {
        int needDeadNum = Mathf.FloorToInt((float)damageNum / (float)BattleMgr.Instance.TroopDic[targetTroopID].TroopHp * BattleMgr.Instance.TroopDic[targetTroopID].LiveUnitList.Count);
        BattleMgr.Instance.TroopDic[targetTroopID].UnitsDeadBySkill(needDeadNum, 2f);
        BattleMgr.Instance.TroopDic[targetTroopID].PlayHeroAttackBySkill();
        TroopHpChange(targetTroopID, fromTroopID, damageNum * -1,isCri,true);
    }

    #endregion

    #region 通知事件

    private void TroopHpChange(int targetTroopID, int doActionTroopID, int hpChangeValue, bool isCri,bool isShowHud,bool needAutoDead = false)
    {
        BattleMgr.Instance.TroopHpChange(doActionTroopID, targetTroopID, hpChangeValue, needAutoDead, isCri, isShowHud);
    }

    #endregion

    #region 武将行动前结算事件
    // 当前在处理的Index
    private int _beforeDoActionIndex = 0;

    private void CheckBeforeDoActionState()
    {
        _fragmentState = FragmentStateType.BeforeAction;
        if (_beforeDoActionList.Count > 0)
        {
            DoBeforeDoAction();
        }
        else
        {
            ChangeFragmentState(FragmentStateType.BeforeSkill);
        }
    }

    private void DoBeforeDoAction()
    {
        //一次性把所有的buf 加血伤血都显示了（头上冒XX buf造成了XX伤害,回血) 播放一个统一的 增减特效
        if (_beforeDoActionIndex < _beforeDoActionList.Count)
        {
            float waitForNextTime = 0;
            bool add = false;
            bool sub = false;
            for (int i = 0; i < _beforeDoActionList.Count; i++)
            {
                BeforeDoAction currBefDoAct = _beforeDoActionList[i];
                if (currBefDoAct._beforeDoActionState == BeforeDoActionState.BuffOff)
                {
                    waitForNextTime = 1f;
                    //Debug.LogFormat("{0}   {1}  buf消失",currBefDoAct._selfTroopID, currBefDoAct._skillEffID);
                    BattleMgr.Instance.TroopBuffOff(currBefDoAct._selfTroopID, currBefDoAct._skillID, currBefDoAct._skillEffID);
                }
                else
                {
                    bool isAdd = true;
                    if (currBefDoAct._beforeDoActionState == BeforeDoActionState.Damage)
                    {
                        isAdd = false;
                        TroopHpChange(currBefDoAct._selfTroopID, currBefDoAct._fromTroopID, currBefDoAct._changeValue * -1, false,false, true);
                        sub = true;
                    }
                    else if (currBefDoAct._beforeDoActionState == BeforeDoActionState.Treatment)
                    {
                        isAdd = true;
                        TroopHpChange(currBefDoAct._selfTroopID, currBefDoAct._fromTroopID, currBefDoAct._changeValue,false,false);
                        add = true;
                    }
                    waitForNextTime = 1f;
                    BattleMgr.Instance.DoBufEff(currBefDoAct._selfTroopID, currBefDoAct._skillID, currBefDoAct._skillEffID, currBefDoAct._changeValue, isAdd);
                }
            }
            if (add)
                BattleMgr.Instance.ShowBufEffect(true, BattleMgr.Instance.TroopDic[_doActionTroopID].gameObject, BattleMgr.Instance.TroopDic[_doActionTroopID].GetTroopCenter());

            if(sub)
                BattleMgr.Instance.ShowBufEffect(false, BattleMgr.Instance.TroopDic[_doActionTroopID].gameObject, BattleMgr.Instance.TroopDic[_doActionTroopID].GetTroopCenter());

            _beforeDoActionIndex = _beforeDoActionList.Count;
            AddInterval(delegate()
            {
                DoBeforeDoAction();
            }, waitForNextTime);
        }
        else 
        {
            ChangeFragmentState(FragmentStateType.BeforeSkill);
        }

        /*
        if (_beforeDoActionIndex < _beforeDoActionList.Count)
        {
            BeforeDoAction currBefDoAct = _beforeDoActionList[_beforeDoActionIndex];
            Debug.Log("*DoBeforeDoAction*  \n <color=#DED65BFF>" + currBefDoAct.ToString() + "</color>");
            float waitForNextTime = 1f;
            if (currBefDoAct._beforeDoActionState == BeforeDoActionState.BuffOff)
            {
                waitForNextTime = 0.2f;
                BattleMgr.Instance.TroopBuffOff(currBefDoAct._selfTroopID, currBefDoAct._skillID, currBefDoAct._skillEffID);
            }
            else if (currBefDoAct._beforeDoActionState == BeforeDoActionState.Damage)
            {
                SkillEffect skillEffect = ConfigManager.Instance.SkillEffectLoader.GetInfoById(currBefDoAct._skillEffID);
                if (skillEffect.battleEffect == 0)
                {
                    waitForNextTime = 0.2f;
                    TroopHpChange(currBefDoAct._selfTroopID, currBefDoAct._fromTroopID, currBefDoAct._changeValue * -1,false,true,true);
                }
                else
                {
                    waitForNextTime = PlayEffect(currBefDoAct) + 0.2f;
                }
            }
            else if (currBefDoAct._beforeDoActionState == BeforeDoActionState.Treatment)
            {
                SkillEffect skillEffect = ConfigManager.Instance.SkillEffectLoader.GetInfoById(currBefDoAct._skillEffID);
                if (skillEffect.battleEffect == 0)
                {
                    waitForNextTime = 0.2f;
                    TroopHpChange(currBefDoAct._selfTroopID, currBefDoAct._fromTroopID, currBefDoAct._changeValue,false,true);
                }
                else
                {
                    waitForNextTime = PlayEffect(currBefDoAct) + 0.2f;
                }
            }
            AddInterval(delegate()
            {
                _beforeDoActionIndex += 1;
                DoBeforeDoAction();
            }, waitForNextTime);
        }
        else
        {
            ChangeFragmentState(FragmentStateType.BeforeSkill);
        }
         * */
    }
    #endregion

    private bool _buildEff = false;

    #region 战斗前释放技能

    private int _beforeSkillResultIndex = 0;

    private int _beforeSkillNeedDoIndex = -1;

    private int _beforeSkillPartIndex = 0;

    private bool _bShowSkillTrigger = false;

    private void CheckBeforeSkillState()
    {
        _fragmentState = FragmentStateType.BeforeSkill;
        //if (_beforeNormalAttackSkillList.Count > 0)
        //{
        //    DoBeforeSkill();
        //}
        //else
        //{
        //    ChangeFragmentState(FragmentStateType.Attack);
        //}
        DoBeforeSkill();
    }

    private bool _useCloseCamera;

    private void DoBeforeSkill()
    {
        if (_beforeSkillResultIndex < _beforeNormalAttackSkillList.Count)
        {
            //Debug.Log(String.Format("*DoBeforeSkill*  \n  PartIndex:{0}  ResultId:{1} \n <color=#DED65BFF>", _beforeSkillPartIndex, _beforeSkillResultIndex) + _beforeNormalAttackSkillList[_beforeSkillResultIndex].ToString() + "</color>");

            if (_beforeNormalAttackSkillList[_beforeSkillResultIndex]._sing == true)
            {
                PlaySing();
                BattleMgr.Instance.PlaySingSkillName(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID);
                _beforeSkillResultIndex += 1;
                _beforeSkillPartIndex = 0;
                //DoBeforeSkill();
                return;
            }
            Skill skillProto = ConfigManager.Instance.SkillLoader.GetInfoById(_beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID);
            int skillType = skillProto.skillType;
            if (skillType == 5 || skillType == 6 || skillType == 7)
            {

                if (_beforeSkillPartIndex < _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList.Count)
                {
                    if (!_buildEff)
                    {
                        _buildEff = true;
                        BattleMgr.Instance.PlayBuidlUpEff(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID);
                    }
                    BattleMgr.Instance.TroopBuffGet(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._targetID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._skillEffID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._value1);
                    _beforeSkillPartIndex += 1;
                    DoBeforeSkill();
                }
                else
                {
                    _beforeSkillResultIndex += 1;
                    _beforeSkillPartIndex = 0;
                    DoBeforeSkill();
                }
            }
            else
            {
                if (_beforeSkillPartIndex < _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList.Count)
                {
                    bool needPlaySkillAction = true;
                    if (skillProto.releaseEffect == 1)
                    {
                        BattleMgr.Instance.PlayFeature(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID);
                        //BattleMgr.Instance.PlaySkillName(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID);
                    }
                    else
                    {
                        //BattleMgr.Instance.PlayFeature(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID);
                        BattleMgr.Instance.PlaySkillName(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID);
                    }

                    if (needPlaySkillAction)
                    {
                        float closeToNeedTime = BattleCameraCtrl.Instance.LookAtTargetTroop(_doActionTroopID);
                        _useCloseCamera = true;
                        AddInterval(delegate()
                        {
                            //BattleMgr.Instance.TroopBuffGet(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._targetID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._skillEffID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._value1);
                        }, closeToNeedTime);

                        int battleEffectId =GetBeIdBySkEff( _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._skillEffID);
                      
                           if ( battleEffectId>0)
                           {
                               BattleEffect be = ConfigManager.Instance.BattleEffectLoader.GetInfoById(battleEffectId);
                               if (be._battleSkillEffectShowType == 1)
                               {
                                   AddInterval(delegate()
                                   {
                                       BattleCameraCtrl.Instance.BackFromTargetTroop();
                                   }, closeToNeedTime);
                                   AddInterval(delegate()
                                   {
                                       AfterBeforeSkillSelect(needPlaySkillAction);

                                   }, closeToNeedTime * 2);
                               }
                               else
                               {
                                   AddInterval(delegate()
                                   {
                                       AfterBeforeSkillSelect(needPlaySkillAction);
                                   }, closeToNeedTime +0.2f);
                               }
                           }
                           else
                           {
                               AddInterval(delegate()
                               {
                                   AfterBeforeSkillSelect(needPlaySkillAction);
                               }, closeToNeedTime +0.2f);
                           }
                    }
                    else
                    {
                        //BattleMgr.Instance.TroopBuffGet(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._targetID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._skillEffID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._value1);
                        AfterBeforeSkillSelect(needPlaySkillAction);
                    }
                }
                else
                {
                    _beforeSkillResultIndex += 1;
                    _beforeSkillPartIndex = 0;
                    _bShowSkillTrigger = false;
                    DoBeforeSkill();
                }
            }
        }
        else
        {
            //if (!_bShowSkillTrigger && _beforeSkillPartIndex == 0 && _beforeSkillResultIndex == 0)
            //{
            //    _bShowSkillTrigger = true;
            //    BattleMgr.Instance.TriggerSkill(_doActionTroopID, -1);
            //    return;
            //}
            ChangeFragmentState(FragmentStateType.Attack);
        }
    }

    public void UITriggerEnd()
    {
        DoBeforeSkill();
    }

    //播放吟唱动作
    public void PlaySing()
    {
        BattleMgr.Instance.TroopDic[_doActionTroopID].TroopPlaySingSkillAction();
        BattleMgr.Instance.TroopDic[_doActionTroopID].PlayHeroSingSkillAction();
    }

    private bool _needCloseCameraToTroop = false;

    private void AfterBeforeSkillSelect(bool needPlaySkillAction)
    {
        if (_beforeSkillPartIndex < _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList.Count)
        {
            if (needPlaySkillAction)
            {
                BattleMgr.Instance.TroopDic[_doActionTroopID].TroopPlaySkillAction();
                BattleMgr.Instance.TroopDic[_doActionTroopID].PlayHeroSkillAction();
            }
            else
            {
                BeforeSkillRealPlayEffect();
            }
        }
        else
        {
            _beforeSkillResultIndex += 1;
            _beforeSkillPartIndex = 0;
            DoBeforeSkill();
        }
    }

    private bool _notNeedBack = false;
    List<int> _skillTag = new List<int>();

    public void BeforeSkillRealPlayEffect()
    {
        float maxSkillEffLast = PlayEffect(_beforeNormalAttackSkillList[_beforeSkillResultIndex]);
        AddInterval(delegate()
        {
            _beforeSkillPartIndex = 0;
            _beforeSkillResultIndex++;
            DoBeforeSkill();
        }, maxSkillEffLast);

        /*
            if (skillProto.releaseAllSkillEff)
            {//所有的skill 产生的skillEff  一次性全部播放完毕
                float maxSkillEffLast = 0;
                for (int i = 0; i < _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList.Count; i++)
                {
                    BattleMgr.Instance.TroopBuffGet(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[i]._targetID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[i]._skillEffID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[i]._value1);
                    float goNextTime = PlayEffect(_beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[i]);
                    if (goNextTime > maxSkillEffLast)
                    {
                        maxSkillEffLast = goNextTime;
                    }
                }
                AddInterval(delegate()
                {
                    _beforeSkillPartIndex = 0;
                    _beforeSkillResultIndex++;
                    DoBeforeSkill();
                }, maxSkillEffLast);
            }
            else
            {//拷贝之前逻辑不动
                _notNeedBack = false;
                if ((_beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList.Count > _beforeSkillPartIndex + 1) && (_beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._targetID == _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex + 1]._targetID))
                {
                    _notNeedBack = true;
                }
                float goNextTime = PlayEffect(_beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]);
                BattleMgr.Instance.TroopBuffGet(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._targetID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._skillEffID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._battleSkillPartList[_beforeSkillPartIndex]._value1);

                AddInterval(delegate()
                {
                    _beforeSkillPartIndex += 1;
                    DoBeforeSkill();
                }, goNextTime);
            }
         * */
    }

    #endregion

    #region 普攻阶段
    
    private int _nowDoNormalAttackTaskIndex = 0;

    private int _nowDoNormalAttackStageIndex = 0;
    
    private string _attackTroopAttackPat;

    private int _hasBackTroopIndex = 0;
    
    public List<int> _beAttackTroopIndexList = new List<int>();

    private void CheckAttackState()
    {
        _fragmentState = FragmentStateType.Attack;
        if (_normalAttackTaskList == null || _normalAttackTaskList.Count == 0)
        {
            ChangeFragmentState(FragmentStateType.AfterSkill);
            return;
        }
        DoNormalAttack();
    }

    private void DoNormalAttack()
    {
        if (_nowDoNormalAttackTaskIndex < _normalAttackTaskList.Count)
        {
            //Debug.Log("*DoNormalAttack*  \n <color=#DED65BFF>" + _normalAttackTaskList[_nowDoNormalAttackTaskIndex].ToString() + "</color>");
            if (_nowDoNormalAttackStageIndex == 0)
            {
                if (_normalAttackTaskList[_nowDoNormalAttackTaskIndex]._normalAttackIndex != -1)
                {
                    BattleMgr.Instance.PlayAttackName(_doActionTroopID);
                    TroopAttack(_normalAttackTaskList[_nowDoNormalAttackTaskIndex]._normalAttackPartList[_normalAttackTaskList[_nowDoNormalAttackTaskIndex]._normalAttackIndex]);
                }
                else
                {
                    _nowDoNormalAttackStageIndex += 1;
                    DoNormalAttack();
                }
            }
            else if (_nowDoNormalAttackStageIndex == 1)
            {
                if (_normalAttackTaskList[_nowDoNormalAttackTaskIndex]._fightBackIndex != -1)
                {
                    TroopFightBack(_normalAttackTaskList[_nowDoNormalAttackTaskIndex]._normalAttackPartList[_normalAttackTaskList[_nowDoNormalAttackTaskIndex]._fightBackIndex]);
                }
                else
                {
                    _nowDoNormalAttackStageIndex += 1;
                    DoNormalAttack();
                }
            }
            else if (_nowDoNormalAttackStageIndex == 2)
            {
                if (_normalAttackTaskList[_nowDoNormalAttackTaskIndex]._sputteringList.Count > 0)
                {
                    TroopSputteringAttack(_normalAttackTaskList[_nowDoNormalAttackTaskIndex]._sputteringList);
                }
                else
                {
                    _nowDoNormalAttackStageIndex += 1;
                    DoNormalAttack();
                }
            }
            else if (_nowDoNormalAttackStageIndex == 3)
            {
                TroopBackToLocalPos();
            }
            else
            {
                _nowDoNormalAttackStageIndex = 0;
                _nowDoNormalAttackTaskIndex += 1;
                DoNormalAttack();
            }
        }
        else
        {
            ChangeFragmentState(FragmentStateType.AfterSkill);
        }
    }

    private void TroopAttack(BattleNormalAttackPart battleNormalAttackPart)
    {
        _hasBackTroopIndex = 0;
        _beAttackTroopIndexList = new List<int>();
        _beAttackTroopIndexList.Add(battleNormalAttackPart._beAttackTroopID);
        BattleMgr.Instance.TroopDic[battleNormalAttackPart._attackTroopID].IntoAttackState(battleNormalAttackPart._beAttackTroopID, battleNormalAttackPart._damageNum,battleNormalAttackPart._isCri);
    }

    private void TroopFightBack(BattleNormalAttackPart battleNormalAttackPart)
    {
        BattleMgr.Instance.TroopDic[battleNormalAttackPart._attackTroopID].IntoAttackState(battleNormalAttackPart._beAttackTroopID, battleNormalAttackPart._damageNum,battleNormalAttackPart._isCri);
    }

    private void TroopSputteringAttack(List<int> battleNormalAttackPartIndexList)
    {
        for (int i = 0; i < battleNormalAttackPartIndexList.Count; i++)
        {
            BattleNormalAttackPart battleNormalAttackPart = _normalAttackTaskList[_nowDoNormalAttackTaskIndex]._normalAttackPartList[battleNormalAttackPartIndexList[i]];
            _beAttackTroopIndexList.Add(battleNormalAttackPart._beAttackTroopID);
            BattleMgr.Instance.TroopDic[battleNormalAttackPart._beAttackTroopID].GetSputteringAttack(battleNormalAttackPart._attackTroopID, battleNormalAttackPart._damageNum,battleNormalAttackPart._isCri);
        }
        _nowDoNormalAttackStageIndex += 1;
        DoNormalAttack();
    }

    private void TroopBackToLocalPos()
    {
        BattleMgr.Instance.TroopDic[_doActionTroopID].BackToOriginal(false);
        for (int i = 0; i < _beAttackTroopIndexList.Count; i++)
        {
            BattleMgr.Instance.TroopDic[_beAttackTroopIndexList[i]].BackToOriginal(false);
        }
    }

    public void OnAttackPartFinish()
    {
        if (_nowDoNormalAttackStageIndex == 3)
        {
            _hasBackTroopIndex += 1;
            if (_hasBackTroopIndex == (_beAttackTroopIndexList.Count + 1))
            {
                _nowDoNormalAttackStageIndex += 1;
                DoNormalAttack();
            }
        }
        else
        {
            _nowDoNormalAttackStageIndex += 1;
            DoNormalAttack();
        }
    }
    #endregion

    #region 追加技能
    private int _afterSkillResultIndex = 0;

    private int _afterSkillNeedDoIndex = -1;
    
    private int _afterSkillPartIndex = 0;

    private void CheckAfterSkillState()
    {
        _fragmentState = FragmentStateType.AfterSkill;
        if (_afterNormalAttackSkillList.Count > 0)
        {
            DoAfterSkill();
        }
        else
        {
            FragmentEnd();
        }
    }

    private void DoAfterSkill()
    {
        if (_afterSkillResultIndex < _afterNormalAttackSkillList.Count)
        {
            //Debug.Log(String.Format("*DoAfterSkill*\n  PartIndex:{0}  ResultIndex:{1}\n <color=#DED65BFF>",_afterSkillPartIndex,_afterSkillResultIndex) + _afterNormalAttackSkillList[_afterSkillResultIndex].ToString() + "</color>");
            if (_afterNormalAttackSkillList[_afterSkillResultIndex]._sing == true)
            {
                PlaySing();
                BattleMgr.Instance.PlaySingSkillName(_doActionTroopID, _afterNormalAttackSkillList[_afterSkillResultIndex]._skillID);
                _afterSkillResultIndex += 1;
                _afterSkillPartIndex = 0;
                //DoBeforeSkill();
                return;
            }
            Skill skillProto = ConfigManager.Instance.SkillLoader.GetInfoById(_afterNormalAttackSkillList[_afterSkillResultIndex]._skillID);
            int skillType = skillProto.skillType;
            if (skillType == 5 || skillType == 6 || skillType == 7)
            {
                if (_afterSkillPartIndex < _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList.Count)
                {
                    if (!_buildEff)
                    {
                        _buildEff = true;
                        BattleMgr.Instance.PlayBuidlUpEff(_doActionTroopID, _afterNormalAttackSkillList[_afterSkillResultIndex]._skillID);
                    }

                    BattleMgr.Instance.TroopBuffGet(_doActionTroopID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._targetID, _afterNormalAttackSkillList[_afterSkillResultIndex]._skillID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._skillEffID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._value1);
                    _afterSkillPartIndex += 1;
                    DoAfterSkill();
                }
                else
                {
                    _afterSkillResultIndex += 1;
                    _afterSkillPartIndex = 0;
                    DoAfterSkill();
                }
            }
            else
            {
                if (_afterSkillPartIndex < _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList.Count)
                {
                    bool needPlaySkillAction = true;
                    if (skillProto.releaseEffect == 1)
                    {
                        BattleMgr.Instance.PlayFeature(_doActionTroopID, _afterNormalAttackSkillList[_afterSkillResultIndex]._skillID);
                    }
                    else
                    {
                        //BattleMgr.Instance.PlaySkillName(_doActionTroopID, _beforeNormalAttackSkillList[_beforeSkillResultIndex]._skillID);
                        BattleMgr.Instance.PlayAddSkillName(_doActionTroopID, _afterNormalAttackSkillList[_afterSkillResultIndex]._skillID);
                    }
                    if (needPlaySkillAction)
                    {
                        float closeToNeedTime = BattleCameraCtrl.Instance.LookAtTargetTroop(_doActionTroopID);
                        AddInterval(delegate()
                        {
                            BattleMgr.Instance.TroopBuffGet(_doActionTroopID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._targetID, _afterNormalAttackSkillList[_afterSkillResultIndex]._skillID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._skillEffID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._value1);
                            BattleCameraCtrl.Instance.BackFromTargetTroop();
                        }, closeToNeedTime);
                        AddInterval(delegate()
                        {
                            AfterAfterSkillSelect(needPlaySkillAction);
                        }, closeToNeedTime * 2);
                    }
                    else
                    {
                        BattleMgr.Instance.TroopBuffGet(_doActionTroopID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._targetID, _afterNormalAttackSkillList[_afterSkillResultIndex]._skillID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._skillEffID, _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList[_afterSkillPartIndex]._value1);
                        AfterAfterSkillSelect(needPlaySkillAction);
                    }
                }
                else
                {
                    _afterSkillResultIndex += 1;
                    _afterSkillPartIndex = 0;
                    DoAfterSkill();
                }
            }
        }
        else
        {
            FragmentEnd();
        }
    }

    private void AfterAfterSkillSelect(bool needPlaySkillAction)
    {
        if (_afterSkillPartIndex < _afterNormalAttackSkillList[_afterSkillResultIndex]._battleSkillPartList.Count)
        {
            if (needPlaySkillAction)
            {
                BattleMgr.Instance.TroopDic[_doActionTroopID].TroopPlaySkillAction();
                BattleMgr.Instance.TroopDic[_doActionTroopID].PlayHeroSkillAction();
            }
            else
            {
                AfterSkillRealPlayEffect();
            }
        }
        else
        {
            _afterSkillResultIndex += 1;
            _afterSkillPartIndex = 0;
            DoAfterSkill();
        }
    }

    public void AfterSkillRealPlayEffect()
    {

        float maxSkillEffLast = PlayEffect(_afterNormalAttackSkillList[_afterSkillResultIndex]);
        AddInterval(delegate()
        {
            _afterSkillResultIndex++;
            _afterSkillPartIndex =0;
            DoAfterSkill();
        }, maxSkillEffLast);
    }

    #endregion

    public void OnStart()
    {
        if (_nilFragment)
        {
            FragmentEnd();
        }
        else
        {
            BattleMgr.Instance.TroopStartAction(_doActionTroopID);
            ChangeFragmentState(FragmentStateType.BeforeAction);
        }
    }

    public void OnUpdate()
    {
        TimeIntervalUpadte();
        BattleMoveEffectUpdate();
    }

    public void RealPlayEffect()
    {
        if (_fragmentState == FragmentStateType.BeforeSkill)
        {
            BeforeSkillRealPlayEffect();
        }
        else
        {
            AfterSkillRealPlayEffect();
        }
    }

    private int GetBeIdBySkEff(int skillEffectID)
    {
        SkillEffect se = ConfigManager.Instance.SkillEffectLoader.GetInfoById(skillEffectID);
        return se.effectId;
    }

    private int GetBeIdBySk(int skillId) 
    {
        Skill sk = ConfigManager.Instance.SkillLoader.GetInfoById(skillId);
        return sk.effectId;
    }

    private void ChangeFragmentState(FragmentStateType fragmentState)
    {
        if (_fragmentState == fragmentState)
        {
            return;
        }
        switch (fragmentState)
        {
            case FragmentStateType.BeforeAction:
                CheckBeforeDoActionState();
                break;
            case FragmentStateType.BeforeSkill:
                CheckBeforeSkillState();
                break;
            case FragmentStateType.Attack:
                CheckAttackState();
                break;
            case FragmentStateType.AfterSkill:
                CheckAfterSkillState();
                break;
        }
    }

    public void ContineFragmentState() 
    {
        switch (_fragmentState)
        {
            case FragmentStateType.BeforeAction:
                CheckBeforeDoActionState();
                break;
            case FragmentStateType.BeforeSkill:
                CheckBeforeSkillState();
                break;
            case FragmentStateType.Attack:
                CheckAttackState();
                break;
            case FragmentStateType.AfterSkill:
                CheckAfterSkillState();
                break;
        }
    }


    private void FragmentEnd()
    {
        BattleMgr.Instance.PlayNextFragment();
    }

    #endregion
}

public class BattleSkillResult
{
    // 需要释放的技能ID
    public int _skillID;
    // 是否只是吟唱
    public bool _sing = false;
    // 包含的skillPart列表
    public List<BattleSkillPart> _battleSkillPartList = new List<BattleSkillPart>();

    public override string ToString()
    {
        Skill s = ConfigManager.Instance.SkillLoader.GetInfoById(_skillID);

        string skillPart="";
        for(int i=0;i<_battleSkillPartList.Count;i++){
            skillPart += "   "+_battleSkillPartList[i].ToString();
        }

        return String.Format("[BattleSkillResult]  \n skillId: {0}  skillType:{3}  isSing:  {1}  \n SkillPart:{2}", _skillID, _sing, skillPart,s.skillType);
    }
}

public class BattleSkillPart
{
    // 技能类型
    public SkillPartState _partState = SkillPartState.Other;
    // 释放的对象的HeroID
    public int _targetID;
    // 释放的skillEffID
    public int _skillEffID;
    // 类型为伤害时，为伤害值，类型为治疗时，为治疗值
    public int _value1;
    // ???
    public int _value2;
    // 造成吸血的值
    public int _vampireNum = -1;
    // 是否是暴击
    public bool _isCri = false;

    public override string ToString()
    {
        SkillEffect se = ConfigManager.Instance.SkillEffectLoader.GetInfoById(_skillEffID);

        return String.Format("skillState:{0}  tagId:{1}  skillEff:{2} skillEffType:{6}  val1:{3}  val2:{4}  吸血:{5}  \n", _partState, _targetID, _skillEffID, _value1, _value2, _vampireNum,se.battleEffect);
    }
}

public class BattleNormalAttackTask
{
    public List<BattleNormalAttackPart> _normalAttackPartList = new List<BattleNormalAttackPart>();
    public int _normalAttackIndex = -1;
    public int _fightBackIndex = -1;
    public List<int> _sputteringList = new List<int>();

    public override string ToString()
    {
        string str ="";
        for(int i=0;i<_normalAttackPartList.Count;i++){
            str += _normalAttackPartList[i].ToString();
        }

        return String.Format("[BattleNormalAttackTask]   \n  AttackIndex:{0}   反击Index:{1}   溅射Indexs:{2}  _nAttackList:{3}", _normalAttackIndex, _fightBackIndex, _sputteringList.ToString(), str);
    }
}

public class BattleNormalAttackPart
{
    // 攻击方ID
    public int _attackTroopID;
    // 被攻击方ID
    public int _beAttackTroopID;
    // 攻击类型
    public NormalAttackState _normalAttackState;
    // 伤害数值
    public int _damageNum;
    // 造成吸血的值
    public int _vampireNum = -1;
    //是否是暴擊
    public bool _isCri = false;


    public override string ToString()
    {
        return String.Format("attackIndex: {0}   beAttackIndex:{1}  _AttackType:{2}   damage:{3}   吸血:{4}  \n ", _attackTroopID, _beAttackTroopID, _normalAttackState, _damageNum, _vampireNum);
    }
}

public class BeforeDoAction
{
    // 行动前结算事件的类型
    public BeforeDoActionState _beforeDoActionState;
    // 结算buff本体的ID
    public int _selfTroopID;
    // buff来自部队的ID
    public int _fromTroopID;
    // buff的SkillID
    public int _skillID;
    // buff的skillEffID
    public int _skillEffID;
    // buff带来的伤害或回血的值
    public int _changeValue;

    public override string ToString()
    {
        return String.Format("[BeforeDo]: \n  结算类型:{0}  作用目标:{1}  来自:{2}   SkillId:{3}   SkillEffId:{4}   val:{5}"
                             ,_beforeDoActionState,_selfTroopID,_fromTroopID,_skillID,_skillEffID,_changeValue);
    }
}

public class BattleMoveEffect
{
    // 目标部队ID
    public int _targetTroopID;
    // 出发部队ID
    public int _fromTroopID;
    // 飞行物
    public GameObject _flyObj;
    // 移动向量
    public Vector3 _moveDir;
    // 是否触发检测
    public bool _makeCheck;
    // skillEffID
    public int _battleEffID;
    // 飞行结束时间
    public float _moveFinishTime;

    public override string ToString()
    {
        return String.Format("[BattleMoveEffect]:  \n  目标:{0}  发射者:{1}  SkillEffId:{2}",_targetTroopID,_fromTroopID,_battleEffID);
    }
}